<template>
  <div class="zoom-on-hover" :class="{ zoomed }" @click="showImg">
    <img class="normal" ref="normal" :src="imgNormal" />
    <img
      :data-enable="true"
      class="zoom"
      ref="zoom"
      :src="imgZoom || imgNormal"
    />
    <icons
      :style="{ left: mouseX + 'px', top: mouseY + 'px' }"
      class="mou-icon"
      name="add"
    />
  </div>
</template>

<script>
import {
  preview,
  setPreviewDefaultOptions,
} from "@/components/v-preview-image"; // 使用setup组合式api时引入方法调用
function pageOffset(el) {
  // -> {x: number, y: number}
  // get the left and top offset of a dom block element
  var rect = el.getBoundingClientRect(),
    scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
    scrollTop = window.pageYOffset || document.documentElement.scrollTop;
  return {
    y: rect.top + scrollTop,
    x: rect.left + scrollLeft,
  };
}

export default {
  name: "Magnify",
  props: {
    imgNormal: {
      type: String,
      default: "",
    },
    imgZoom: {
      type: String,
      default: "",
    },
    scale: {
      type: Number,
      default: 1.7,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    imgs: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      mouseX: -100,
      mouseY: -100,
      scaleFactor: 1,
      resizeCheckInterval: null,
      zoomed: false,
      // viewerOption: {
      //   initialCoverage: 1,
      //   movable: false,
      //   navbar: false, //缩略图
      //   title: false, // 图片名称
      //   button: false, //关闭按钮
      //   inline: false, //是否限制在行内展示
      //   // 设置按钮显示
      //   toolbar: false,
      //   filter(image) {
      //     return image.dataset.enable;
      //   },
      // },
    };
  },
  mounted: function () {
    if (this.$props.scale) {
      this.scaleFactor = parseInt(this.$props.scale);
      this.$refs.zoom.style.transform = "scale(" + this.scaleFactor + ")";
    }
    //window.addEventListener("mousemove", this.handleMouseMove);
    this.initEventLoaded();
    this.initEventResized();
    setPreviewDefaultOptions({
      enabledMaskClose: true, // 是否开启点击遮罩关闭(默认为true)
      enabledEscClose: false, // 是否开启esc按键关闭(默认为true)
      enabledMouseZoom: false, // 是否开启鼠标滚轮缩放(默认为true)
      activeColor: "green", // 预览图中选中图片的背景颜色(默认为rgba(239, 84, 78, 0.7))
    });
  },
  updated: function () {
    this.initEventLoaded();
  },
  beforeUnmount: function () {
    //this.resizeCheckInterval && clearInterval(this.resizeCheckInterval);
  },
  unmounted() {
    // 在组件销毁时移除事件监听
    window.removeEventListener("mousemove", this.handleMouseMove);
  },
  methods: {
    showImg() {
      const list = this.imgs.filter((e) => !e.Pic.includes(".mp4"));
      preview(0, list, "LargePic");
    },
    handleMouseMove(event) {
      // 获取组件的位置
      const rect = this.$el.getBoundingClientRect();
      // 更新鼠标坐标
      this.mouseX = event.clientX - rect.left - 30;
      this.mouseY = event.clientY - rect.top - 30;
    },
    touchzoom: function (event) {
      if (this.disabled) return;
      this.move(event);
      this.zoomed = !this.zoomed;
    },
    zoom: function () {
      if (!this.disabled) this.zoomed = true;
    },
    unzoom: function () {
      if (!this.disabled) this.zoomed = false;
    },
    move: function (event) {
      if (this.disabled || !this.zoomed) return;
      var offset = pageOffset(this.$el);
      var zoom = this.$refs.zoom;
      var normal = this.$refs.normal;
      var relativeX = event.clientX - offset.x + window.pageXOffset;
      var relativeY = event.clientY - offset.y + window.pageYOffset;
      var normalFactorX = relativeX / normal.offsetWidth;
      var normalFactorY = relativeY / normal.offsetHeight;
      var x =
        normalFactorX *
        (zoom.offsetWidth * this.scaleFactor - normal.offsetWidth);
      var y =
        normalFactorY *
        (zoom.offsetHeight * this.scaleFactor - normal.offsetHeight);
      zoom.style.left = -x + "px";
      zoom.style.top = -y + "px";
    },
    initEventLoaded: function () {
      // emit the "loaded" event if all images have been loaded
      var promises = [this.$refs.zoom, this.$refs.normal].map(function (image) {
        return new Promise(function (resolve, reject) {
          image.addEventListener("load", resolve);
          image.addEventListener("error", reject);
        });
      });
      var component = this;
      Promise.all(promises).then(function () {
        component.$emit("loaded");
      });
    },
    initEventResized: function () {
      var normal = this.$refs.normal;
      var previousWidth = normal.offsetWidth;
      var previousHeight = normal.offsetHeight;
      var component = this;
      this.resizeCheckInterval = setInterval(function () {
        if (
          previousWidth != normal.offsetWidth ||
          previousHeight != normal.offsetHeight
        ) {
          previousWidth = normal.offsetWidth;
          previousHeight = normal.offsetHeight;
          component.$emit("resized", {
            width: normal.width,
            height: normal.height,
            fullWidth: normal.naturalWidth,
            fullHeight: normal.naturalHeight,
          });
        }
      }, 1000);
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="less">
.zoom-on-hover {
  position: relative;
  overflow: hidden;
  height: 100%;
  width: 100%;

  .mou-icon {
    pointer-events: none;
    position: absolute;
    width: 60px;
    height: 60px;
  }
}
.zoom-on-hover .normal {
  width: 100%;
  object-fit: cover;
  max-height: 100%;
}
.zoom-on-hover .zoom {
  position: absolute;
  opacity: 0;
  transform-origin: top left;
}
.zoom-on-hover.zoomed .zoom {
  opacity: 1;
}
.zoom-on-hover.zoomed .normal {
  opacity: 1;
}
</style>
